package com.wyh.controller.feemanagementcontroller;

import com.wyh.common.result.Result;
import com.wyh.domain.dto.feemanagementdto.PaymentDTO;
import com.wyh.domain.po.feemanagementpo.*;
import com.wyh.service.feemanagementservice.*;
import io.swagger.annotations.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Api(tags="收款记录+导入")
@RequestMapping("/paymentRecords")
public class PaymentRecordsController {
    @Autowired
    private PaymentRecordsService paymentRecordsService;
    @Autowired
    private BillService billService;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private PaymentmethodService paymentmethodService;
    @Autowired
    private ICustomerService customerService;

    @ApiOperation("删除收款记录")
    @DeleteMapping("/del/{id}")
    public Result<String> delete(@PathVariable Long id) {
        PaymentRecords paymentRecords = paymentRecordsService.findById(id);
        if (paymentRecords == null) {
            return Result.error("404", "没有找到该记录");
        }
        if (paymentRecords.getState() == 0) {
            Integer result = paymentRecordsService.deleteById(id);
            return result > 0 ? Result.success() : Result.error("500", "删除失败");
        } else {
            return Result.error("500", "记录状态不为失败，不可以删除");
        }
    }

    @ApiOperation("查询退款操作中的退款金额和付款业主")
    @GetMapping("/findRe")
    public Result<List<PaymentDTO>> findRefund(Long billid){
        return Result.success(paymentRecordsService.findBy(billid));
    }
    @ApiOperation("分页查询")
    @GetMapping ("/page")
    public Result<Map<String, Object>> findPage(@RequestParam Integer pageNum,
                           @RequestParam Integer pageSize,
                           @RequestParam(required = false) String payer,
                           @RequestParam(required = false) String collectiontime,
                           @RequestParam(required = false) String collectionnumber,
                           @RequestParam(required = false) String paynumber,
                           @RequestParam(required = false) String payee,
                           @RequestParam(required = false) String customername,
                           @RequestParam(required = false) String name,
                           @RequestParam(required = false) String receivingaccount,
                           @RequestParam(required = false) Integer state) {
        Map<String, Object> params = new HashMap<>();
        params.put("pageNum", pageNum);
        params.put("pageSize", pageSize);
        params.put("payer", payer);
        params.put("collectiontime", collectiontime);
        params.put("collectionnumber", collectionnumber);
        params.put("paynumber", paynumber);
        params.put("payee", payee);
        params.put("customername", customername);
        params.put("name", name);
        params.put("receivingaccount", receivingaccount);
        params.put("state", state);

        List<PaymentRecords> data = paymentRecordsService.selectPage(params);
        Map<String, Object> res = new HashMap<>();
        res.put("data", data);
        Integer total = paymentRecordsService.selectTotal(params);
        res.put("total", total);
        return Result.success(res);
    }

    @ApiOperation(value = "批量导入", notes = "通过Excel文件批量导入数据")
    @PostMapping("/import")
    public ResponseEntity<StreamingResponseBody> importExcel(@ApiParam(value = "要上传的文件", required = true) @RequestParam("file") MultipartFile file) throws Exception {
        List<PaymentRecords> paymentRecordsList = new ArrayList<>();
        List<Billes> billesList = new ArrayList<>();
        List<Paymentmethod> paymentmethodList = new ArrayList<>();
        List<Projectes> projectesList = new ArrayList<>();

        boolean hasErrors = false;
        String importMessage = "导入成功";

        try (InputStream is = file.getInputStream(); XSSFWorkbook workbook = new XSSFWorkbook(is)) {
            XSSFSheet sheet = workbook.getSheetAt(0);
            XSSFCellStyle errorCellStyle = workbook.createCellStyle();
            XSSFFont font = workbook.createFont();
            font.setColor(IndexedColors.RED.getIndex());
            errorCellStyle.setFont(font);

            // 增加错误信息列
            XSSFRow headerRow = sheet.getRow(0);
            XSSFCell errorHeaderCell = headerRow.createCell(9);
            errorHeaderCell.setCellValue("错误原因");

            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                XSSFRow row = sheet.getRow(i);
                PaymentRecords paymentRecords = new PaymentRecords();
                StringBuilder errorMessage = new StringBuilder();

                // 检查收款时间
                Cell dateCell = row.getCell(0);
                if (dateCell != null && dateCell.getCellType() == CellType.NUMERIC) {
                    Date collectiontime = dateCell.getDateCellValue();
                    paymentRecords.setCollectiontime(collectiontime);
                } else {
                    errorMessage.append("收款时间不能为空; ");
                }

                // 检查收款流水号
                Cell collectionNumberCell = row.getCell(1);
                if (collectionNumberCell != null) {
                    String collectionnumber = "";
                    switch (collectionNumberCell.getCellType()) {
                        case STRING:
                            collectionnumber = collectionNumberCell.getStringCellValue().trim();
                            break;
                        case NUMERIC:
                            collectionnumber = String.valueOf((long) collectionNumberCell.getNumericCellValue());
                            break;
                        default:
                            break;
                    }
                    if (!collectionnumber.isEmpty()) {
                        paymentRecords.setCollectionnumber(collectionnumber);
                    } else {
                        errorMessage.append("收款流水号不能为空; ");
                    }
                } else {
                    errorMessage.append("收款流水号不能为空; ");
                }

                // 检查支付流水号
                Cell paynumberCell = row.getCell(2);
                if (paynumberCell != null) {
                    String paynumber = "";
                    switch (paynumberCell.getCellType()) {
                        case STRING:
                            paynumber = paynumberCell.getStringCellValue().trim();
                            break;
                        case NUMERIC:
                            paynumber = String.valueOf((long) paynumberCell.getNumericCellValue());
                            break;
                        default:
                            break;
                    }
                    if (!paynumber.isEmpty()) {
                        paymentRecords.setPaynumber(paynumber);
                    } else {
                        errorMessage.append("支付流水号不能为空; ");
                    }
                } else {
                    errorMessage.append("支付流水号不能为空; ");
                }

                // 检查付款人
                Cell payerCell = row.getCell(3);
                if (payerCell != null && payerCell.getCellType() == CellType.STRING) {
                    String payer = payerCell.getStringCellValue().trim();
                    if (!payer.isEmpty()) {
                        paymentRecords.setPayer(payer);
                    } else {
                        errorMessage.append("付款人不能为空; ");
                    }
                } else {
                    errorMessage.append("付款人不能为空; ");
                }

                // 检查付款方式
                Cell paymentMethodCell = row.getCell(4);
                if (paymentMethodCell != null && paymentMethodCell.getCellType() == CellType.STRING) {
                    String paymentMethod = paymentMethodCell.getStringCellValue().trim().toLowerCase();
                    if (!paymentMethod.isEmpty()) {
                        List<String> allowedPaymentMethods = Arrays.asList("现金", "支票", "微信支付").stream()
                                .map(String::toLowerCase)
                                .collect(Collectors.toList());
                        if (allowedPaymentMethods.contains(paymentMethod)) {
                            Paymentmethod method = new Paymentmethod();
                            method.setName(paymentMethod);
                            paymentmethodList.add(method);
                        } else {
                            errorMessage.append("不支持的付款方式: ").append(paymentMethod).append("; ");
                        }
                    } else {
                        errorMessage.append("付款方式不能为空; ");
                    }
                } else {
                    errorMessage.append("付款方式不能为空; ");
                }

                // 检查收款人
                Cell payeeCell = row.getCell(5);
                if (payeeCell != null && payeeCell.getCellType() == CellType.STRING) {
                    String payee = payeeCell.getStringCellValue().trim();
                    if (!payee.isEmpty()) {
                        Billes verification = billService.findByPayee(payee);
                        if (verification == null) {
                            errorMessage.append("收款人" + payee + "不存在于系统中。");
                        } else {
                            billesList.add(verification);
                        }
                    }
                }

                // 检查收款账户
                Cell receivingAccountCell = row.getCell(6);
                if (receivingAccountCell != null && receivingAccountCell.getCellType() == CellType.STRING) {
                    String receivingAccount = receivingAccountCell.getStringCellValue().trim();
                    if (!receivingAccount.isEmpty()) {
                        Projectes projectes = projectService.findByReceivingAccount(receivingAccount);
                        if (projectes == null) {
                            projectes = new Projectes();
                            projectes.setReceivingaccount(receivingAccount);
                        }
                        projectesList.add(projectes);
                    } else {
                        errorMessage.append("收款账户不能为空; ");
                    }
                } else {
                    errorMessage.append("收款账户不能为空; ");
                }

                // 检查收款金额
                Cell amountCell = row.getCell(7);
                if (amountCell != null && amountCell.getCellType() == CellType.NUMERIC) {
                    BigDecimal amount = BigDecimal.valueOf(amountCell.getNumericCellValue());
                    if (amount.compareTo(BigDecimal.ZERO) > 0) {
                        paymentRecords.setAmount(amount);
                    } else {
                        errorMessage.append("收款金额不能为空; ");
                    }
                } else {
                    errorMessage.append("收款金额不能为空; ");
                }

                // 备注信息
                Cell remarksCell = row.getCell(8);
                if (remarksCell != null && remarksCell.getCellType() == CellType.STRING) {
                    String remarks = remarksCell.getStringCellValue().trim();
                    paymentRecords.setRemarks(remarks);
                }

                // 根据错误信息长度添加到相关列表或错误信息单元格
                if (errorMessage.length() == 0) {
                    paymentRecordsList.add(paymentRecords);
                } else {
                    hasErrors = true;
                    XSSFCell errorCell = row.createCell(9);
                    errorCell.setCellValue(errorMessage.toString());
                    errorCell.setCellStyle(errorCellStyle);
                }
            }

            if (!hasErrors) {
                for (Paymentmethod paymentmethod : paymentmethodList) {
                    paymentmethodService.insert(paymentmethod);
                }

                for (Billes billes : billesList) {
                    billService.insertB(billes);
                }

                for (PaymentRecords paymentRecords : paymentRecordsList) {
                    paymentRecordsService.insert(paymentRecords);
                }

                for (Projectes projectes : projectesList) {
                    projectService.insert(projectes);
                }
                for (PaymentRecords paymentRecords : paymentRecordsList) {
                    // 付款业主匹配和自动核销处理放在插入之后进行
                    Customers customers = customerService.findByName(paymentRecords.getPayer());
                    if (customers != null) {
                        paymentRecords.setPayer(customers.getName());
                        paymentRecords.setCustomerid(customers.getId());

                        // 自动核销处理
                        List<Billes> unpaidBilles = billService.findUnpaidBillsByCustomerId(customers.getId());
                        for (Billes billes : unpaidBilles) {
                            if (billes.getArrears().compareTo(paymentRecords.getAmount()) == 0) {
                                billes.setArrears(new BigDecimal(0));
                                billService.update(billes);
                                paymentRecords.setBillid(Long.valueOf(billes.getBillnumber()));
                                break;
                            }
                        }
                    }
                }
                importMessage = "导入成功";
            } else {
                importMessage = "导入失败";
            }

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            workbook.write(bos);
            workbook.close();

            ByteArrayResource resource = new ByteArrayResource(bos.toByteArray());

            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=errorsMessage.xlsx");

            // 使用StreamingResponseBody返回多部分响应
            String finalImportMessage = importMessage;
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .headers(headers)
                    .contentType(MediaType.MULTIPART_FORM_DATA)
                    .body(outputStream -> {
                        String boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
                        outputStream.write(("--" + boundary + "\r\n").getBytes());
                        outputStream.write("Content-Disposition: form-data; name=\"message\"\r\n\r\n".getBytes());
                        outputStream.write(finalImportMessage.getBytes());
                        outputStream.write(("\r\n--" + boundary + "\r\n").getBytes());
                        outputStream.write("Content-Disposition: form-data; name=\"file\"; filename=\"errorsMessage.xlsx\"\r\n".getBytes());
                        outputStream.write("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\r\n\r\n".getBytes());
                        outputStream.write(resource.getByteArray());
                        outputStream.write(("\r\n--" + boundary + "--\r\n").getBytes());
                    });

        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(outputStream -> outputStream.write("导入失败".getBytes()));
        }
    }
}
